import 'package:amap/amap.dart';
import 'package:amap/src/pick/paged_list_view.dart';
import 'package:amap/src/pick/poi_bean.dart';
import 'package:amap/src/pick/poi_search_api.dart';
import 'package:amap/src/pick/search_box_widget.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class PickLocationPage extends StatefulWidget {
  final LatLng initialTarget;

  const PickLocationPage({Key key, this.initialTarget}) : super(key: key);

  @override
  _PickLocationPageState createState() => _PickLocationPageState();
}

class _PickLocationPageState extends State<PickLocationPage> {
  PickLocationModel model;

  @override
  void initState() {
    super.initState();
    model = PickLocationModel();
  }

  @override
  Widget build(BuildContext context) {
    model.context = context;
    return ChangeNotifierProvider.value(
      value: model,
      child: Scaffold(
        body: Stack(
          children: <Widget>[
            MapView(
              creationParams: MapCreationParams(
                  settings: UiSettings(
                    zoomControlsEnabled: false,
                    compassEnabled: false,
                  ),
                  cameraPosition: CameraPosition(zoom: 20),
                  myLocationStyle: MyLocationStyle(
                    myLocationType: MyLocationType.followNoCenter,
                  )),
            ),
            Positioned(left: 16, top: 16, child: buildCloseButton(context)),
            Positioned(right: 16, top: 16, child: buildOkayButton(context)),
            Positioned(
                left: 0,
                right: 0,
                bottom: 0,
                child: Column(
                  crossAxisAlignment: CrossAxisAlignment.end,
                  children: <Widget>[
                    Padding(
                      padding: const EdgeInsets.all(8.0),
                      child: FloatingActionButton(
                        mini: true,
                        child: Icon(Icons.location_searching),
                        onPressed: () {
                          model.gotoMyLocation(context);
                        },
                      ),
                    ),
                    SearchPoiWidget(),
                  ],
                ))
          ],
        ),
      ),
    );
  }

  Widget buildCloseButton(BuildContext context) {
    return SafeArea(
      child: IconButton(
        icon: CircleAvatar(
          radius: 16,
          backgroundColor: Colors.white,
          child: Icon(
            Icons.clear,
            color: Colors.grey,
          ),
        ),
        onPressed: () {
          Navigator.of(context).pop(null);
        },
      ),
    );
  }

  Widget buildOkayButton(BuildContext context) {
    final theme = Theme.of(context);
    return SafeArea(
      child: SizedBox(
        width: 64,
        child: RaisedButton(
          color: theme.primaryColor,
          padding: EdgeInsets.zero,
          shape: StadiumBorder(),
          child: Text(
            "确定",
            style: TextStyle(color: Colors.white),
          ),
          onPressed: () {
            Navigator.of(context).pop(null);
          },
        ),
      ),
    );
  }
}

class PickLocationModel extends ChangeNotifier implements MapEventListener {
  static PickLocationModel of(BuildContext context) =>
      Provider.of(context, listen: false);

  MapViewController mapViewController;

  SearchTextOptions searchTextOptions;
  SearchAroundOptions searchAroundOptions;
  bool searchAroundModel;

  Key poiListKey;
  MapLocation currentLocation;

  PickLocationModel() {
    mapViewController = MapViewController(this);
    searchTextOptions = SearchTextOptions(key: PoiSearch.demoKey);
    searchAroundOptions = SearchAroundOptions(key: PoiSearch.demoKey);
    searchAroundModel = true;
    poiListKey = UniqueKey();
  }

  @override
  void onCameraChange(CameraPosition cameraPosition) {
    // TODO: implement onCameraChange
  }

  @override
  void onCameraChangeFinish(CameraPosition cameraPosition) {
    // TODO: implement onCameraChangeFinish
  }

  @override
  void onInfoWindowClicked(MarkerOptions camera) {
    // TODO: implement onInfoWindowClicked
  }

  @override
  void onMarkerClicked(MarkerOptions camera) {
    // TODO: implement onMarkerClicked
  }

  @override
  void onMarkerDragEnd(MarkerOptions camera) {
    // TODO: implement onMarkerDragEnd
  }

  @override
  void onMarkerDragStart(MarkerOptions camera) {
    // TODO: implement onMarkerDragStart
  }

  @override
  void onMarkerDragged(MarkerOptions camera) {
    // TODO: implement onMarkerDragged
  }

  @override
  BuildContext context;

  @override
  void onMapClicked(MapClickedEvent event) {
    // TODO: implement onMapClicked
  }

  @override
  void onMapLoaded() {
    print("onMapLoaded");
    mapViewController.getMyLocation().then((location) {
      print("onMapLoaded -> getMyLocation -> $location");
      if (currentLocation != location) {
        searchAround(location);
      }
    });
  }

  void searchAround(MapLocation location) {
    searchAroundModel = true;
    currentLocation = location;
    searchAroundOptions
      ..location = location.target
      ..page = 1;
    poiListKey = ValueKey(location);
    notifyListeners();
  }

  void searchText(String keyword) {
    searchAroundModel = false;
    searchTextOptions
      ..keywords = [keyword]
      ..page = 1;
    poiListKey = ValueKey(keyword);
    notifyListeners();
  }

  Future<PageData<PoiBean>> getPagedData(int page, int rows) async {
    if (searchAroundModel) {
      searchAroundOptions
        ..location = currentLocation?.target
        ..page = page
        ..offset = rows;
      final result = await PoiSearch.searchAround(searchAroundOptions);
      if (result != null && result.success) {
        return PageData.success(result.count, result.poiList);
      } else {
        return PageData.failed("暂无数据");
      }
    } else {
      searchTextOptions
        ..page = page
        ..offset = rows;
      final result = await PoiSearch.searchText(searchTextOptions);
      if (result != null && result.success) {
        return PageData.success(result.count, result.poiList);
      } else {
        return PageData.failed("暂无数据");
      }
    }
  }

  void gotoMyLocation(BuildContext context) {
    mapViewController.gotoMyLocation();
  }
}

class SearchPoiWidget extends StatefulWidget {
  @override
  _SearchPoiWidgetState createState() => _SearchPoiWidgetState();
}

class _SearchPoiWidgetState extends State<SearchPoiWidget> {
  @override
  Widget build(BuildContext context) {
    final model = PickLocationModel.of(context);
    return Container(
      height: 280,
      color: Colors.white,
      child: Column(
        children: <Widget>[
          SearchBoxWidget(
            backgroundColor: const Color(0xfff0f0f0),
            onValueChanged: (String value) {
              model.searchText(value);
            },
          ),
          Expanded(
            child: Consumer<PickLocationModel>(
              builder: (BuildContext context, PickLocationModel model,
                  Widget child) {
                return PagedListView<PoiBean>(
                  padding: EdgeInsets.zero,
                  key: model.poiListKey,
                  itemBuilder: (int index, PoiBean item) =>
                      PoiWidget(bean: item),
                  pageBuilder: model.getPagedData,
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}

class PoiWidget extends StatelessWidget {
  final PoiBean bean;

  const PoiWidget({Key key, @required this.bean}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Padding(
          padding: EdgeInsets.symmetric(horizontal: 16),
          child: Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Text(
                bean.name,
                style: const TextStyle(fontSize: 15, color: Color(0xff252525)),
              ),
              SizedBox(height: 4),
              Text(
                bean.address,
                style: const TextStyle(fontSize: 13, color: Color(0xff999999)),
              ),
            ],
          ),
        ),
        Divider(indent: 16, height: 32),
      ],
    );
  }
}
